//
//	CalcEngine -- mem
//	A general C++ class that directly supports a calculator interface
//
//	You may freely copy, distribute and reuse the code in this example.
//	NeXT disclaims any warranty of any kind, expressed or implied, as to
//	its fitness for any particular use.
//
//	Created 8-21-90
//
extern "Objective-C"
{
#import <objc/error.h>
}

#import "CalcEngine.h"

// Create an instance of the class and initialize flags for start-up
CalcEngine::CalcEngine()
{	
    //the buffer that holds the first number entered
    accumulator = 0;
	
    //the current operator
    op = 0;
}

// Clear the state of the calculator engine.
void CalcEngine::clear()
{
    setOperation(0);
    accumulator = 0;
}

// Set the current operation (+ - * / ),  0 is no operation.
void CalcEngine::setOperation(int whichOp)
{
    op = whichOp;
}

// Called when one of the operation keys is pressed.
double CalcEngine::operationKeys(int whichOp, double firstNum)
{
    double result;

    switch(whichOp){
	case DIVIDE:		// Indicates a series of numbers and
	case MULTIPLY:		// operations.  For example: 1 + 2 + 3 + ...
	case SUBTRACT:
	case ADD:
	{
	    if (op)
		result = equalsKey(firstNum);
	    else
		result = firstNum;
	    setOperation(whichOp);
	    accumulator = result;
	    break;
	}
	default:		// Indicates first number has just been
	{			// entered.
	    result = 0;
	    break;
	}
    }
    return result;
}

// Do the actual calculation.  This is called when the equals key is pressed or
// when an operation key is pressed in a series of numbers.
double CalcEngine::equalsKey(double secondNum)
{
    double result;

    switch(op){
	case DIVIDE:
	{
	    if(secondNum == 0) {
		clear();
		NX_RAISE(0, "divideByZero", 0);
	    }
	    result = accumulator / secondNum;
	    break;
	}
	case MULTIPLY:
	{
	    result = accumulator * secondNum;
	    break;
	}
	case SUBTRACT:
	{
	    result = accumulator - secondNum;
	    break;
	}
	case ADD:
	{
	    result = accumulator + secondNum;
	    break;
	}
	default:{
	    result = secondNum;
	    break;
	}
    }
    clear();
    return result;
}